package com.cxk.hr.controller;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.cxk.hr.pojo.Department;
import com.cxk.hr.pojo.Employee;
import com.cxk.hr.pojo.History;
import com.cxk.hr.pojo.Position;
import com.cxk.hr.pojo.Salary;
import com.cxk.hr.security.RoleSign;
import com.cxk.hr.service.DepartmentService;
import com.cxk.hr.service.EmployeeService;
import com.cxk.hr.service.HistoryService;
import com.cxk.hr.service.PositionService;
import com.cxk.hr.service.SalaryService;
import com.cxk.hr.service.impl.EmployeeServiceImpl;
import com.cxk.hr.service.impl.HistoryServiceImpl;
import com.cxk.hr.service.impl.SalaryServiceImpl;
import com.cxk.hr.util.CaptchaUtil;
import com.cxk.hr.util.MTimeUtil;

@Controller
@RequestMapping("/employee")
public class EmployeeController {
	@Autowired
	EmployeeService employeeService = new EmployeeServiceImpl();
	@Autowired
	SalaryService salaryService = new SalaryServiceImpl();
	@Autowired
	private DepartmentService departmentService;
	@Autowired
	HistoryService historyService = new HistoryServiceImpl();
	@Autowired
	private PositionService positionService;

	private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

	@RequestMapping("/login")
	public String toLogin() {
		return "login";
	}

	/**
	 * 输出验证码图片
	 * 
	 * @param request
	 * @param response
	 * 
	 * @throws ServletException
	 * @throws IOException
	 */
	@RequestMapping(value = "/captcha", method = RequestMethod.GET)
	@ResponseBody
	public void captcha(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		CaptchaUtil.outputCaptcha(request, response);
	}

	/**
	 * 登录验证
	 * 
	 * @param session
	 * @param request
	 * @param username(登录输入的账号,实为employee_number)
	 * @param password
	 * @param captcha
	 * @param isRememberMe
	 * 
	 * @return
	 * 
	 * @throws Exception
	 */
	@RequestMapping("/checkLogin")
	public String checkLogin(HttpSession session, HttpServletRequest request, String username, String password,
			String captcha, @RequestParam(value = "isRememberMe", defaultValue = "0") Integer isRememberMe)
			throws Exception {
		String error = null;// 页面显示的错误信息
		if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
			return "login";
		}

		if (captcha == null || captcha.isEmpty()) {
			error = "验证码必须填写";
			request.setAttribute("error", error);
			return "login";
		}
		if (!session.getAttribute("randomString").equals(captcha.toUpperCase())) {
			error = "验证码错误";
			request.setAttribute("error", error);
			return "login";
		}

		Employee employee = new Employee();
		employee.setEmployeeNumber(Integer.parseInt(username));
		employee.setPassword(password);
		/*
		 * 基于spring MVC实现认证过程
		 * 
		 * 认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)
		 * 以检验用户是否合法.最常见的"实体/凭证"组合便是"用户名/密码"组合
		 */

		/*
		 * 1.收集实体/凭据信息
		 * 
		 * UsernamePasswordToken支持最常见的用户名/密码的认证机制.同时,
		 * 由于它实现了RememberMeAuthenticationToken接口,我们可以通过令牌设置"记住我"的功能.
		 * 但是，"已记住"和"已认证"是有区别的:已记住的用户仅仅是非匿名用户,
		 * 你可以通过subject.getPrincipals()获取用户信息. 但是它并非是认证通过的用户,
		 * 当你访问需要认证用户的功能时,你仍然需要重新提交认证信息 
		 * 这一区别可以参考淘宝网站,网站会默认记住登录的用户,再次访问网站时,对于非敏感的页面功能,页面上会显示记住的用户信息,
		 * 但是当你访问网站账户信息时仍然需要再次进行登录认证
		 */

		// 获取基于username(employee_name)和password的令牌
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		// 登录界面如果勾选了记住我
		if (isRememberMe == 1) {
			token.setRememberMe(true);
		}
		/*
		 * 2.提交实体/凭据信息
		 * 
		 * Subject currentUser = SecurityUtils.getSubject();
		 * currentUser.login(token);
		 * 收集了实体/凭据信息之后,我们可以通过SecurityUtils工具类,获取当前的用户,然后通过调用login方法提交认证
		 */
		Subject currentEmplpyee = SecurityUtils.getSubject();
		try {
			currentEmplpyee.login(token);
		}

		/*
		 * 2.认证
		 * 
		 * 当执行currentUser.login(token)时,会先执行ShiroDbRealm.doGetAuthorizationInfo(
		 * )进行认证 此处无需比对,比对的逻辑Shiro会做,我们可以获取一个和令牌相关的正确的验证信息 例如:new
		 * SimpleAuthenticationInfo(empolyee.getName(),empolyee.getPassword(),
		 * getName());
		 */

		/*
		 * 3.认证处理
		 * 
		 * 如果login方法执行过程中抛出异常,那么将认为认证失败,Shiro有着丰富的层次鲜明的异常类来描述认证失败的原因
		 * 如果login方法执行完毕且没有抛出任何异常信息,那么便认为用户认证通过,
		 * 之后在应用程序任意地方调用SecurityUtils.getSubject()都可以获取到当前认证通过的用户实例,
		 * 使用subject.isAuthenticated()判断用户是否已验证都将返回true.  
		 * 
		 */

		catch (UnknownAccountException e) {// com.cxk.hr.security/SecurityRealm中
			error = "用户名/密码错误";
		} catch (IncorrectCredentialsException e) {// com.cxk.hr.security/CustomCredentialsMatcher中
			error = "用户名/密码错误";
		} catch (ExcessiveAttemptsException e) {// com.cxk.hr.security/CustomCredentialsMatcher中
			error = "登录失败多次，账户锁定10分钟";
		}
		if (error != null) {
			// 出错了，返回登录页面
			request.setAttribute("error", error);
			return "login";
		} else {

			// 登录成功
			System.out.println("登录成功");

			// 将密码md5加密加盐(盐值为employee_number)
			ByteSource salt = ByteSource.Util.bytes(username);
			Md5Hash md5Hash = new Md5Hash(password, salt, 1024);
			// 从数据库中查询用户用信息
			employee = employeeService.checkLogin(Integer.parseInt(username), md5Hash.toString());
			session.setAttribute("loged", employee);// 记录登录员工

			String level = employee.getPosition().getLevel();// 获取登录员工的职称
			// 根据登录员工的职称转发到不同页面
			if (level.equals("人事部主任")) {
				System.out.println("--------------1");
				return "admin/index1";
			} else if (level.equals("人事部员工")) {
				System.out.println("--------------2");
				return "admin/index2";
			} else if (level.equals("部门主任")) {
				System.out.println("--------------3");
				return "admin/index3";
			} else {// 部门员工
				System.out.println("--------------4");
				return "admin/index4";
			}

		}
	}

	/**
	 * 员工管理 添加员工
	 * 
	 * @param model
	 */
	@RequestMapping("/add")
	@RequiresRoles(value = RoleSign.ADMIN)
	public String add(Employee employee, String date) {
		employee.setBirthday(MTimeUtil.stringParse(date));
		employeeService.addEmployee(employee);
		return "forward:/employee/listPage?pageNo=0&pageSize=10000";
	}

	/*
	 * 无权限时返回的页面
	 */
	@RequestMapping("/unauthorized")
	public String toUnauthorized() {
		return "unauthorized";
	}

	/**
	 * 返回主页
	 */
	@RequestMapping("/welcome")
	public String toWelcome() {
		return "welcome";
	}

	/**
	 * 员工管理 删除
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping("/{id}/delete")
	@RequiresRoles(value = RoleSign.ADMIN)
	public String deleteById(@PathVariable Integer id) {
		employeeService.deleteEmployee(id);
		return "forward:/employee/listPage";
	}

	/**
	 * 员工管理 查看
	 * 
	 * @param id
	 * @param model
	 */
	@RequestMapping("/{id}/detial")
	public String selectEmployee(@PathVariable Integer id, Model model) {
		Employee employee = employeeService.selectEmployeeById(id);
		Salary salary = salaryService.selectById(id);
		model.addAttribute("employee", employee);
		model.addAttribute("salary", salary);
		return "admin/employee_detail";
	}

	/**
	 * 员工管理 修改
	 * 
	 * @param model
	 * @param id
	 */
	@RequestMapping("/{id}/toUpdate")
	@RequiresRoles(value = RoleSign.ADMIN)
	public String toUpdate(Model model, @PathVariable Integer id) {
		Employee employee = employeeService.selectEmployeeById(id);
		model.addAttribute("employee", employee);
		List<Department> dList = departmentService.selectList();
		model.addAttribute("dList", dList);
		List<Position> pList = positionService.selectList();
		model.addAttribute("pList", pList);
		return "admin/employee_update";
	}

	@RequestMapping("/{id}/update")
	@RequiresRoles(value = RoleSign.ADMIN)
	public String updateById(@PathVariable Integer id, Employee employee, String date, String status,
			HttpSession session) {
		employee.setId(id);
		employee.setBirthday(MTimeUtil.stringParse(date));
		// 得到操作人员的名字
		Employee employee2 = (Employee) session.getAttribute("loged");
		employeeService.updateEmployee(employee, status, employee2.getName());
		return "forward:/employee/listPage?pageNo=0&pageSize=10000";
	}

	/**
	 * 员工管理 员工表
	 * 
	 * @param model
	 * @param pageNo
	 * @param pageSize
	 */
	@RequestMapping("/listPage")
	@RequiresRoles(value = RoleSign.ADMIN)
	public String selectList(Model model, Integer pageNo, Integer pageSize) {
		List<Employee> employees = employeeService.selectListByPage(pageNo, pageSize);
		model.addAttribute("employees", employees);
		return "admin/employee_list";
	}

	@RequestMapping("/logout ")
	public String logout(HttpSession session) {
		session.removeAttribute("loged");
		// 登出操作
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return "login";
	}

	/**
	 * 查看个人信息
	 * 
	 * @param id
	 * @param model
	 */
	@RequestMapping("/oneself/{id}/detial")
	public String selectEmployee2(@PathVariable Integer id, Model model) {
		Employee employee = employeeService.selectEmployeeById(id);
		Salary salary = salaryService.selectById(id);
		model.addAttribute("employee", employee);
		model.addAttribute("salary", salary);
		return "admin/oneself_detail";
	}

	/**
	 * 查看个人信息里修改个人信息
	 * 
	 * @param model
	 * @param id
	 */
	@RequestMapping("/oneself/{id}/toUpdate")
	public String toUpdate2(Model model, @PathVariable Integer id) {
		Employee employee = employeeService.selectEmployeeById(id);
		model.addAttribute("employee", employee);
		return "admin/oneself_update";
	}

	/**
	 * 主界面搜索框
	 * 
	 * @param model
	 * @param input
	 * @param pageNo
	 */
	@RequestMapping("/search")
	public String search(Model model, String input, Integer pageNo) {
		List<Employee> employees = employeeService.search(input, pageNo);
		model.addAttribute("employees", employees);
		System.out.println("-----------------------employees:" + employees);
		System.out.println("-----------------------input:" + input);
		return "admin/search_result";
	}

	/**
	 * 员工管理 添加员工
	 * 
	 * @param model
	 */
	@RequestMapping("/toAdd")
	@RequiresRoles(value = RoleSign.ADMIN)
	public String toAdd(Model model) {
		List<History> eList = historyService.selectList(0, 10000);
		model.addAttribute("employeeNumber", eList.get(eList.size() - 1).getEmployeeNumber() + 1);
		List<Department> dList = departmentService.selectList();
		model.addAttribute("dList", dList);
		List<Position> pList = positionService.selectList();
		model.addAttribute("pList", pList);
		return "admin/employee_add";
	}

	/**
	 * 修改个人信息
	 * 
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping("/oneself/{id}/UpdataEmp")
	public String updataemp(@PathVariable Integer id, Model model) {
		Employee employee = (Employee) employeeService.findEmpById(id);
		model.addAttribute("employee", employee);
		List<Department> depart = employeeService.findAlldept();
		model.addAttribute("depart", depart);
		List<Position> pos = employeeService.findAllpos();
		model.addAttribute("pos", pos);
		return "employee_update";
	}

	/**
	 * 查询部门员工
	 * 
	 * @param depar
	 */
	@RequestMapping("/checkpeo")
	@ResponseBody
	public Object checkpeo(Integer depar) {
		List<Employee> emp = employeeService.findEmpByDeptNum(depar);
		return emp;
	}

	/**
	 * 申请加班成功
	 * 
	 * @param departmentNumber
	 * @param employeeNumber
	 * @param date
	 * @throws ParseException
	 */
	@RequestMapping("/addSuccess")
	public String addSuccess(String departmentNumber, String employeeNumber, String date) throws ParseException {

		Date date1 = simpleDateFormat.parse(date);
		Integer department = Integer.parseInt(departmentNumber);
		Integer employee = Integer.parseInt(employeeNumber);
		Integer i = employeeService.addOverTime(department, employee, date1);
		return "forward:addcheck";

	}
	/**
	 * 申请请假成功
	 * 
	 * @param id
	 * @param departmentNumber
	 * @param start
	 * @param end
	 * @param days
	 * @param type
	 * @param reason
	 * @return
	 * @throws ParseException
	 */
	@RequestMapping("/addLeaveSuccess") 
	public String addLeaveSuccess(@PathVariable Integer id, String departmentNumber, String start, String end,
			String days, String type, String reason) throws ParseException {
		Employee employee = (Employee) employeeService.findEmpById(id);
		Date startdate = simpleDateFormat.parse(start);
		Date enddate = simpleDateFormat.parse(end);
		Integer i = employeeService.addLeave(employee.getEmployeeNumber(), employee.getDepartmentNumber(), startdate,
				enddate, days, type, reason);
		System.out.println(i + "pppppppppppppppppppppppppppppp");
		return "forward:oneself/{id}/selflea";
	}

	/**
	 * 更新修改数据
	 * 
	 * @param id
	 * @param name
	 * @param password
	 * @param notes
	 * @param date
	 * @param gender
	 * @param telephone
	 * @param positionNumber
	 * @param departmentNumber
	 * @param email
	 * @param address
	 * @param education
	 * @param model
	 * @param session
	 * @return
	 * @throws ParseException
	 */
	@RequestMapping("/update") 
	public String update(@PathVariable Integer id, String name, String password, String notes, String date,
			String gender, String telephone, String positionNumber, String departmentNumber, String email,
			String address, String education, Model model, HttpSession session) throws ParseException {
		// ,String gender,Date date,String telephone,String email,String
		// address,String education,String departmentNumber,String
		// positionNumber,String status,
		Employee employee = (Employee) employeeService.findEmpById(id);
		employee.setName(name);
		employee.setNotes(notes);
		employee.setPassword(password);
		employee.setGender(gender);
		Date date1 = simpleDateFormat.parse(date);
		employee.setBirthday(date1);
		employee.setTelephone(telephone);
		employee.setEmail(email);
		employee.setAddress(address);
		employee.setEducation(education);

		Department dept = employeeService.findDepartByName(departmentNumber);
		employee.setDepartmentNumber(dept.getDepartmentNumber());
		Position pos = employeeService.findPosByName(positionNumber);
		employee.setPositionNumber(pos.getPositionNumber());
		/*
		 * employee.getPosition().setName(positionNumber);
		 * employee.getHistory().setStatus(status);
		 */
		int num = employeeService.updataEmpById(employee);

		System.out.println("成功" + num);
		return "forward:CheckMes";
	}
	/**
	 * 
	 * 
	 * 
	 * 
	 * 
	 * 
	 * 
	 */

	/*
	 * @RequestMapping("/logout1.do") public String logout1(HttpSession
	 * session){ session.removeAttribute("loged"); return "login"; }
	 */

}
